﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace Gmantis.Controls
{
    public class TypedEnumeratorWrapper<TItem> : IEnumerator<TItem>, IEnumerator, IDisposable
    {
        // Fields
        private readonly IEnumerator _baseEnumerator;

        // Methods
        public TypedEnumeratorWrapper(IEnumerator baseEnumerator)
        {
            if (baseEnumerator == null)
            {
                throw new ArgumentNullException("baseEnumerator");
            }
            this._baseEnumerator = baseEnumerator;
        }

        public bool MoveNext()
        {
            return this._baseEnumerator.MoveNext();
        }

        public void Reset()
        {
            this._baseEnumerator.Reset();
        }

        void IDisposable.Dispose()
        {
            IDisposable disposable = this._baseEnumerator as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }
        }

        // Properties
        public TItem Current
        {
            get
            {
                return (TItem)this._baseEnumerator.Current;
            }
        }

        object IEnumerator.Current
        {
            get
            {
                return this._baseEnumerator.Current;
            }
        }
    }

    public class TypedEnumerableWrapper<TItem>: IEnumerable<TItem>, IEnumerable
    {
        // Fields
        private readonly IEnumerable _baseEnumerable;

        // Methods
        public TypedEnumerableWrapper(IEnumerable baseEnumerable)
        {
            if (baseEnumerable == null)
            {
                throw new ArgumentNullException("baseEnumerable");
            }
            this._baseEnumerable = baseEnumerable;
        }

        public IEnumerator<TItem> GetEnumerator()
        {
            return new TypedEnumeratorWrapper<TItem>(this.BaseEnumerable.GetEnumerator());
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.BaseEnumerable.GetEnumerator();
        }

        // Properties
        protected IEnumerable BaseEnumerable
        {
            get
            {
                return this._baseEnumerable;
            }
        }
    }

    public static class TypedCollectionWrapperExtensions
    {
        public static IEnumerable<TItem> GetTypedEnumerableWrapper<TItem>(this IEnumerable baseEnumerable)
        {
            return new TypedEnumerableWrapper<TItem>(baseEnumerable);
        }

        public static IEnumerable<UIElement> GetTypedUIElementCollectionWrapper(this UIElementCollection collection)
        {
            return collection;
        }
    }
}
